package com.gitee.wsl.mathematics.matrix.mat4.ext


import com.gitee.wsl.mathematics.matrix.ext.setIdentity
import com.gitee.wsl.mathematics.matrix.mat4.Matrix4
import com.gitee.wsl.mathematics.matrix.mat4.MutableMatrix4
import com.gitee.wsl.mathematics.vector.vec3.Vector3

/** @return the squared scale factor on the X axis */
val <T:Number> Matrix4<T, *, *>.scaleXSqr
    get() = m00 * m00 + m01 * m01 + m02 * m02

/** @return the squared scale factor on the Y axis */
val <T:Number> Matrix4<T, *, *>.scaleYSqr
    get() = m10 * m10 + m11 * m11 + m12 * m12

/** @return the squared scale factor on the Z axis */
val <T:Number> Matrix4<T, *, *>.scaleZSqr
    get() = m20 * m20 + m21 * m21 + m22 * m22

/** @return the scale factor on the X axis (non-negative) */
val <T:Number> Matrix4<T, *, *>.scaleX
    get() = if (m01.isApproxZero() && m02.isApproxZero())
        abs(m00) else sqrt(scaleXSqr)

/** @return the scale factor on the Y axis (non-negative) */
val <T:Number> Matrix4<T, *, *>.scaleY
    get() = if (m10.isApproxZero() && m12.isApproxZero())
        abs(m11) else sqrt(scaleYSqr)

/** @return the scale factor on the X axis (non-negative) */
val <T:Number> Matrix4<T, *, *>.scaleZ
    get() = if (m20.isApproxZero() && m21.isApproxZero())
        abs(m22) else sqrt(scaleZSqr)

val <T:Number> Matrix4<T, *, *>.scale get() = createVec3(scaleX,scaleY,scaleZ)

fun<T:Number> MutableMatrix4<T, *, *>.setScale(x: T, y: T, z: T){
    setIdentity()
    m00 = x
    m11 = y
    m22 = z
}

fun<T:Number> MutableMatrix4<T, *, *>.setScale(scale: Vector3<T,*>)
   = setScale(scale.x, scale.y, scale.z)


/*fun<T:Number> MutableMatrix4<T, *, *>.scale(x: T, y: T = x, z: T = y) {
    for (i in 0..3) {
        this[i,0] *= x
        this[i,1] *= y
        this[i,2] *= z

        *//*proxy[ i] *= x
        proxy[4 + i] *= y
        proxy[8 + i] *= z*//*
    }
}

fun<T:Number> MutableMatrix4<T, *, *>.scale(scale: Vector3<T,*>) = scale(scale.x, scale.y, scale.z)
*/

/**
 * Inplace operation: Scales this matrix by the given factor.
 */
fun<T:Number> MutableMatrix4<T, *, *>.scale(x: T, y: T = x, z: T = y) = mul33(
    x, zero, zero,
    zero, y, zero,
    zero, zero, z
)

/**
 * Inplace operation: Scales this matrix by the given factors.
 */
fun<T:Number> MutableMatrix4<T, *, *>.scale(s: Vector3<T,*>) = mul33(
    s.x, zero, zero,
    zero, s.y, zero,
    zero, zero, s.z
)
